package com.example.basic.base;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.Locale;

/**
 * 全局上下文
 *
 * @author tds
 */
@Component
@EnableConfigurationProperties(SystemProperties.class)
public class Context implements InitializingBean {
    private final static Logger logger = LoggerFactory.getLogger(Context.class);

    /**
     * 站点相关配置属性
     */
    @Autowired
    public SystemProperties systemProperties;

    /**
     * 系统语言设置
     */
    public Locale locale = Constants.DEFAULT_LOCALE;

    /**
     * 系统环境变量
     */
    @Autowired
    private Environment env = null;

    /**
     * 多语言资源文件
     * 延迟注入，避免启动报错
     */
    @Autowired
    @Lazy
    private MessageSource messageSource;

    private MessageSourceAccessor messages = null;

    @Override
    public void afterPropertiesSet() throws Exception {
        Assert.notNull(this.env, "A Environment must be set");
        Assert.notNull(this.messageSource, "A MessageSource must be set");
        logger.debug("lms.root: [{}]", systemProperties.getRoot());

        // 获取是否启用调试模式配置，默认不启用
        logger.debug("lms.debug: [{}]", systemProperties.isDebug());

        // 获取主域名
        logger.debug("lms.master-domain: [{}]", systemProperties.getMasterDomain());

        // 获取端口号
        logger.debug("lms.master-port: [{}]", systemProperties.getMasterPort());

        // 获取是否启用多机构模式配置
        logger.debug("lms.multi-org-enable: [{}]", systemProperties.isMultiOrgEnable());

        // 默认多语言设置
        locale = getProperty("lms.lang", Locale.class, Constants.DEFAULT_LOCALE);
        logger.debug("lms.lang : [{}]", locale);

        messages = new MessageSourceAccessor(messageSource);
    }

    /**
     * 获取当前系统是否是调试模式
     *
     * @return boolean
     */
    public boolean isDebug() {
        return systemProperties.isDebug();
    }

    /**
     * 获取当前系统是否启用多机构模式
     *
     * @return boolean
     */
    public boolean isMultiOrgEnable() {
        return systemProperties.isMultiOrgEnable();
    }

    /**
     * 获取配置文件里面的配置项
     *
     * @param key 配置项
     * @return String
     */
    public String getProperty(String key) {
        return env.getProperty(key);
    }

    public String getProperty(String key, String defaultValue) {
        return env.getProperty(key, defaultValue);
    }

    public <T> T getProperty(String key, Class<T> clazz) {
        return env.getProperty(key, clazz);
    }

    public <T> T getProperty(String key, Class<T> clazz, T defaultValue) {
        return env.getProperty(key, clazz, defaultValue);
    }

    /**
     * 获取多语言文本
     *
     * @param code 文本编号
     * @return
     */
    public String getMessage(String code) {
        return getMessage(code, Constants.DEFAULT_LOCALE);
    }

    public String getMessage(String code, Locale locale) {
        return messages.getMessage(code, locale);
    }

    public String getMessage(String code, Object[] args) {
        return getMessage(code, args, Constants.DEFAULT_LOCALE);
    }

    public String getMessage(String code, Object[] args, Locale locale) {
        return messages.getMessage(code, args, locale);
    }

    public String getMessage(String code, Object[] args, String defaultMessage) {
        return getMessage(code, args, defaultMessage, Constants.DEFAULT_LOCALE);
    }

    public String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
        return messages.getMessage(code, args, defaultMessage, locale);
    }

    /**
     * 获取应用根目录
     */
    public String getAppRoot() {
        return systemProperties.getRoot();
    }


    public MessageSource getMessageSource() {
        return messageSource;
    }

    public void setMessageSource(MessageSource messageSource) {
        this.messageSource = messageSource;
    }

    public MessageSourceAccessor getMessages() {
        return messages;
    }

    public void setMessages(MessageSourceAccessor messages) {
        this.messages = messages;
    }

    public void setLocale(Locale locale) {
        this.locale = locale;
    }
}
